/**
 * @Title: DynamicJob.java
 * @Package com.kaver.job.core.djob
 * @author roc
 * @date 2020年4月15日 下午4:27:28
 * @version V1.0
 * @copyright kaver
 */
package com.kaver.job.core.djob;

import java.util.List;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.CollectionUtils;

import com.google.gson.Gson;
import com.kaver.job.core.biz.AdminBiz;
import com.kaver.job.core.biz.model.AddJobParam;
import com.kaver.job.core.biz.model.JobInfo;
import com.kaver.job.core.biz.model.QueryJobParam;
import com.kaver.job.core.biz.model.ReturnT;
import com.kaver.job.core.biz.model.StopJobParam;
import com.kaver.job.core.biz.model.UpdateJobParam;
import com.kaver.job.core.executor.JobExecutor;
import com.kaver.job.core.executor.impl.JobSpringExecutor;

/**
 * @ClassName: DynamicJob
 * @Description: 动态job
 * @author roc
 * @date 2020年4月15日 下午4:27:28
 * 
 */
public class DynamicJob {
    private static final Logger logger = LoggerFactory.getLogger(DynamicJob.class);
    @Autowired
    private JobSpringExecutor jobSpringExecutor;
    private String oneCountExecutorRouteStrategy = "RANDOM";   // 执行器路由策略
    private String rateExecutorRouteStrategy = "CONSISTENT_HASH";   // 执行器路由策略
    private String oneCountExecutorBlockStrategy = "SERIAL_EXECUTION";   // 阻塞处理策略
    private String rateExecutorBlockStrategy = "DISCARD_LATER";   // 阻塞处理策略
    /**
     * 创建只执行一次的job
     * 
     * @return jobId
     */
    public boolean addOneCountJob(String handler, String serialNo, String param) {
        return addJob(handler, "00 00 00 01 01 ? 1970", serialNo, param, true, 0, oneCountExecutorRouteStrategy, oneCountExecutorBlockStrategy);
    }
    /**
     * 创建只执行一次的job
     * @param delay延迟时间 单位秒
     * @return jobId
     */
    public boolean addOneCountJob(String handler, String serialNo, String param, long delay) {
        return addJob(handler, "00 00 00 01 01 ? 1970", serialNo, param, true, delay, oneCountExecutorRouteStrategy, oneCountExecutorBlockStrategy);
    }
    /**
     * 创建按频率执行的job
     * 
     * @return jobId
     */
    public boolean addRateJob(String handler, String cron,String serialNo, String param) {
        return addJob(handler, cron, serialNo, param, false, 0, rateExecutorRouteStrategy, rateExecutorBlockStrategy);
    }
    /**
     * 创建按频率执行的job
     * @param delay延迟时间 单位秒
     * @return jobId
     */
    public boolean addRateJob(String handler, String cron,String serialNo, String param, long delay) {
        return addJob(handler, cron, serialNo, param, false, delay, rateExecutorRouteStrategy, rateExecutorBlockStrategy);
    }
    /**
     * 创建job
     * 
     * @return jobId
     */
    public boolean addJob(String handler, String cron, String serialNo, String param,boolean oneCount,long delay,String executorRouteStrategy,String executorBlockStrategy) {
        try {
            List<AdminBiz> bizs = JobExecutor.getAdminBizList();
            AddJobParam addJobParam = new AddJobParam();
            addJobParam.setAppname(jobSpringExecutor.getAppname());
            addJobParam.setExecutorBlockStrategy(executorBlockStrategy);
            addJobParam.setExecutorHandler(handler);
            addJobParam.setExecutorParam(param);
            addJobParam.setExecutorRouteStrategy(executorRouteStrategy);
            addJobParam.setJobCron(cron);
            addJobParam.setJobDesc(serialNo);
            addJobParam.setOneCount(oneCount);
            addJobParam.setDelay(delay);
            if (!CollectionUtils.isEmpty(bizs)) {
                AdminBiz biz = bizs.get(0);
                ReturnT<String> returnT = biz.addJob(addJobParam);
                if (returnT.getCode() == ReturnT.SUCCESS_CODE) {
                    logger.info("创建job成功:" + new Gson().toJson(addJobParam));
                    return true;
                } else {
                    logger.error("创建job失败[" + returnT.toString() + "]");
                }
            }
        } catch (Exception e) {
            logger.error("创建job失败", e);
        }
        return false;
    }
    /**
     * 停止job
     * 
     * @param jobId
     */
    public boolean stopJob(String serialNo, String handler) {
        try {
            List<AdminBiz> bizs = JobExecutor.getAdminBizList();
            if (!CollectionUtils.isEmpty(bizs)) {
                AdminBiz biz = bizs.get(0);
                StopJobParam stopJobParam = new StopJobParam();
                stopJobParam.setExecutorHandler(handler);
                stopJobParam.setAppname(jobSpringExecutor.getAppname());
                stopJobParam.setJobDesc(serialNo);
                ReturnT<String> returnT = biz.stopJob(stopJobParam);
                if (ReturnT.SUCCESS_CODE == returnT.getCode()) {
                    return true;
                } else {
                    logger.error("停止job失败[" + returnT.toString() + "]");
                }
            }
        } catch (Exception e) {
            logger.error("停止job失败", e);
        }
        return false;
    }
    
    public JobInfo queryJob(String serialNo, String handler) {
        try {
            List<AdminBiz> bizs = JobExecutor.getAdminBizList();
            if (!CollectionUtils.isEmpty(bizs)) {
                AdminBiz biz = bizs.get(0);
                QueryJobParam queryJobParam = new QueryJobParam();
                queryJobParam.setAppName(jobSpringExecutor.getAppname());
                queryJobParam.setHandler(handler);
                queryJobParam.setSerialNo(serialNo);
                ReturnT<JobInfo> returnT = biz.queryJob(queryJobParam);
                if (ReturnT.SUCCESS_CODE == returnT.getCode()) {
                    return returnT.getContent();
                } else {
                    return null;
                }
            } else {
                throw new RuntimeException("查询失败");
            }
        } catch (Exception e) {
            throw new RuntimeException("查询失败");
        }
    }
    
    /**
     * 更新job
     * 
     * @return jobId
     */
    public boolean updateJob(String serialNo, String handler, String cron,  String param) {
        try {
            List<AdminBiz> bizs = JobExecutor.getAdminBizList();
            UpdateJobParam updateJobParam = new UpdateJobParam();
            updateJobParam.setAppname(jobSpringExecutor.getAppname());
            updateJobParam.setExecutorHandler(handler);
            updateJobParam.setExecutorParam(param);
            updateJobParam.setJobCron(cron);
            updateJobParam.setJobDesc(serialNo);
            if (!CollectionUtils.isEmpty(bizs)) {
                AdminBiz biz = bizs.get(0);
                ReturnT<String> returnT = biz.updateJob(updateJobParam);
                if (returnT.getCode() == ReturnT.SUCCESS_CODE) {
                    return true;
                } else {
                    logger.error("创建job失败[" + returnT.toString() + "]");
                }
            }
        } catch (Exception e) {
            logger.error("创建job失败", e);
        }
        return false;
    }
}
